package bar.dark.lee.alarm.common;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;

public class DBSQLite
{
	private static DBSQLite sqllite = new DBSQLite();
	
	private static SQLiteDatabase db = null;
	
	public static String dataBaseName = "CrazyAlarm";
	
	public static DBSQLite getInstance(Context context)
	{
		if (db == null)
		{
			startDatabase(context);
		}
		return sqllite;
	}
	
	public void beginTansaction(Context context) throws Exception
	{
		if (db == null)
		{
			startDatabase(context);
		}
		
		db.beginTransaction();
	}
	
	public void setTransactionSuccessful()
	{
		db.setTransactionSuccessful();
	}
	
	public void endTransaction(Context context) throws Exception
	{
		if (db == null)
		{
			startDatabase(context);
		}
		
		db.endTransaction();
	}
	
	private static void startDatabase(final Context context)
	{
		try
		{
			db = SQLiteDatabase.openDatabase("/data/data/" 
					+ context.getPackageName() + "/" 
					+ dataBaseName, null, SQLiteDatabase.CREATE_IF_NECESSARY);
		} catch (Exception e)
		{
			if (db != null)
			{
				db.close();
			}
			
			db = null;
			e.printStackTrace();
		}
	}
	
	/**
	 * 테이블을 지운다
	 * @param tableName 테이블 명
	 */
	public void dropTable(final Context context, String tableName)
	{
		try
		{
			db.execSQL("drop table "+ tableName);
		} catch (SQLException e)
		{
			rollback(context);
		} 
	}
	
	/**
	 * 테이블을 생성한다.
	 * @param sql 테이블을 생성할 쿼리문
	 */
	public void createTable(Context context, String sql)
	{
		db.execSQL(sql);
	}

	/**
	 * 데이터를 삽입한다.
	 * @param content 데이터를 삽입할 키와 벨류값
	 * @param tableName 테이블 이름
	 */
	public int insert(Context context, final HashMap<String, String> content, String tableName)
	{
		try
		{
			if (db == null)
			{
				startDatabase(context);
			}
			
			ContentValues cv = getHashMapToContent(content);
			
			db.insert(tableName, null, cv);
		} catch (Exception e)
		{
			rollback(context);
			return -1;
		}
		
		return 0;
	}
	
	/**
	 * 데이터를 가져온다.
	 * @param sql 쿼리문
	 * @param parse 데이터 파싱후 처리 부분
	 */
	public void selectMapTile(Context context, String sql, final ParseSelectData parse)
	{
		Cursor c = null;
		try
		{
			if (db == null)
			{
				startDatabase(context);
			}
			
			c = db.rawQuery(sql, null);
			ParseSelectData parseSelectData = parse;
			parseSelectData.resultData(c);
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally {
			if (c != null)
			{
				c.close();
			}
		}
	}
	
	/**
	 * 데이터를 가져온다. 반환 커서
	 * @param context
	 * @param sql
	 * @return
	 */
	public Cursor select(Context context, String sql)
	{
		Cursor c = null;
		try
		{
			if (db == null)
			{
				startDatabase(context);
			}
			
			c = db.rawQuery(sql, null);
		} catch (Exception e)
		{
			e.printStackTrace();
			return c;
		} 
		
		return c;
	}
	
	public interface ParseSelectData
	{
		public abstract void resultData(Cursor c);
	}
	
	/**
	 * 데이터를 업데이트 한다.
	 * @param tableName 테이블명
	 * @param content 바꿀 키와 값
	 * @param whereClause where 구문 
	 * @param whereArgs where 값들 
	 */
	public int update(final Context context, String tableName, final HashMap<String, String> content, 
			final String whereClause, String [] whereArgs)
	{
		try
		{
			if (db == null)
			{
				startDatabase(context);
			}
			
			ContentValues cv = getHashMapToContent(content);
			
			db.update(tableName, cv, whereClause, whereArgs);
		} catch (Exception e)
		{
			rollback(context);
			return -1;
		}
		
		return 0;
	}
	
	/**
	 * 데이터를 지운다.
	 * @param tableName 테이블명
	 * @param whereClause where 구문
	 * @param whereArgs where 값들 
	 */
	public int delete(final Context context, String tableName, String whereClause, String [] whereArgs)
	{
		try
		{
			if (db == null)
			{
				startDatabase(context);
			}
			
			db.delete(tableName, whereClause, whereArgs);
		} catch (Exception e)
		{
			rollback(context);
			return -1;
		} 
		
		return 0;
	}
	
	public void rollback(Context context)
	{
//		db.setTransactionSuccessful();
//		showToast(context);
	}
	
	public void closeDatabese()
	{
		if (db != null)
		{
			if (db.isOpen())
			{
				db.close();
				db = null;
			}
		}
	}
	
	public boolean isOpen()
	{
		return db.isOpen();
	}
	
	private void showToast(Context context)
	{
		Toast.makeText(context, "다시 시도해 주세요.", Toast.LENGTH_SHORT).show();
	}
	
	public ContentValues getHashMapToContent(HashMap<String, String> hashMap)
	{
		Iterator<Entry<String, String>> iter = hashMap.entrySet().iterator();
		
		ContentValues cv = new ContentValues();
		
		for (int i = 0; i < hashMap.size(); i++)
		{
			Entry<String, String> entry = iter.next();
			cv.put(entry.getKey(), (String) entry.getValue());
		}
		
		return cv;
	}
}
